-- UIMagicScrolls
-- Create by luohj Jan/13/2015
-- 魔法卷轴

require "game/logic/base/Item"
require "game/ui/base/TextColorM"
require "game/ui/form/spell/UISpellOperation"
require "game/ui/form/spell/UISelectTarget"
require "game/ui/form/common/UIBonusNotify"
require "game/ui/form/stone/UIStoneSelectTarget"

-- UIMagicScrolls继承自Layer
UIMagicScrolls = class("UIMagicScrolls", function()
    return cc.Layer:create();
end);

function UIMagicScrolls.create()
    return UIMagicScrolls.new();
end

-- 魔法卷轴类型  土、水、火、气、光、暗
local MAGIC_TYPE_SOIL       = EARTH    -- 土
local MAGIC_TYPE_WATER      = WATER    -- 水
local MAGIC_TYPE_FIRE       = FIRE     -- 火
local MAGIC_TYPE_GAS        = THUNDER  -- 气
local MAGIC_TYPE_LIGHT      = LIGHTER  -- 光
local MAGIC_TYPE_DARK       = DARK     -- 暗

-- 菜单按钮类型
local MENU_TYPE_STYLE   = 1;   -- 系别
local MENU_TYPE_RANK    = 2;   -- 阶位
local MENU_TYPE_SPECIAL = 3;   -- 特殊

-- 特殊菜单中的分页类型
local SPECIAL_SKILL_LIGHT = 1;  -- 光
local SPECIAL_SKILL_DARK  = 2;  -- 暗
local SPECIAL_SKILL_WATER = 3;  -- 水
local SPECIAL_SKILL_SLIME = 4;  -- 冈布奥主动技能
local SPECIAL_SKILL_ELEMENT = 99;  -- 元素球
local SPECIAL_SKILL_DRAGON = 5;    -- 龙语魔法

-- TODO 暂时仅开放两个特殊分页
local SPECIAL_PAGES = { SPECIAL_SKILL_LIGHT, SPECIAL_SKILL_DARK, SPECIAL_SKILL_SLIME, SPECIAL_SKILL_ELEMENT, SPECIAL_SKILL_DRAGON};

-- 魔法卷轴格最大行数和列数
local MAX_GRID_ROW    = 3;
local MAX_GRID_COLUMN = 2;

-- 魔法卷轴类型数量
local MAGIC_KINDS_COUNT = 6;

-- 当前选中的类型
local selectType = MENU_TYPE_STYLE;

-- 当前的魔法系别
local spellType = {MAGIC_TYPE_FIRE, MAGIC_TYPE_WATER, MAGIC_TYPE_SOIL, MAGIC_TYPE_GAS, MAGIC_TYPE_LIGHT, MAGIC_TYPE_DARK};

-- 魔法卷轴类型种类
local genre = {BUFF, SPECIAL, AOE, DAMAGE, RECOVER, DEBUFF};

-- 当前右侧tab选中的位置索引
local rightTabIndex = 1;

-- 内部函数声明
local sortMagic;

---------------------------------
----- 页面的数据维护 -------------

-- 按照魔法类型得到的玩家所有技能，当界面关闭时需要清空
local type2skills = nil;

-- 按照品质得到的玩家所有技能，当界面关闭时需要清空
local rank2skills = nil;

-- 特殊分页的玩家所有技能，当界面关闭时需要清空
local specialSkills = nil;

-- 获取技能显示的详细信息
local getSkillDetail = function(list)
    if nil == list then return {} end

    local r = {};
    for _, v in pairs(list) do
        local data = {};
        local itemInfo = SpellM.query(v);
        local name = itemInfo.desc;
        data.classId = v;
        data.rank = itemInfo["rank"] or 0;
        data.require_mp = SpellM.calcSpellCost(v) or 0;
        data.name = name or "";
        data.genre = itemInfo["genre"] or 0;
        data.style = itemInfo["style"] or 0;
        data.cast_skill_id = SpellM.query(v, "cast_skill_id");
        data.icon = SkillM.query(data.cast_skill_id, "icon");
        data.count = ItemM.getAmount(ME.user, v);
        table.insert(r, data);
    end
    return r;
end

-- 获取技能信息（按照魔法类型）
local getSkillsByType = function(type)
    if nil ~= type2skills then return type2skills[type] end

    -- 初始化一把
    type2skills = {};
    for i = 1, #spellType do
        local spells = ItemM.getItemsBySkillStyle(ME.user, spellType[i]);
        local count = 0;
        if spells ~= nil then
            for _, classId in pairs(spells) do
                count = count + ItemM.getAmount(ME.user, classId);
            end
        end

        type2skills[spellType[i]] = {
            list = getSkillDetail(spells),
            count = count
        };
        table.sort(type2skills[spellType[i]]["list"], sortMagic);
    end

    return type2skills[type];
end

-- 获取技能信息（按照品质）
local getSkillsByRank = function(rank)
    if nil ~= rank2skills then return rank2skills[rank] end

    -- 初始化一把
    rank2skills = {};
    for i = 1, 5 do
        local spells = ItemM.getItemsBySkillRank(ME.user, i);
        local count = 0;
        if spells ~= nil then
            for _, classId in pairs(spells) do
                count = count + ItemM.getAmount(ME.user, classId);
            end
        end

        rank2skills[i] = {
            list = getSkillDetail(spells),
            count = count
        }
    end

    return rank2skills[rank];
end

-- 获取第一个有技能的品质
local getFirstRank = function()
    for i = 1, 5 do
        local skills = getSkillsByRank(i);
        if nil ~= skills and skills['count'] > 0 then
            return i;
        end
    end
    return 1;
end

-- 获取特殊技能信息
local getSpecialSkills = function(index)
    if nil ~= specialSkills then
        return specialSkills[index] or {};
    end

    -- 初始化一把
    specialSkills = {};
    for i = 1, #SPECIAL_PAGES do
        local page = SPECIAL_PAGES[i];
        local skills = {};
        if page == SPECIAL_SKILL_SLIME then
            skills = SlimeSkillM.getAllSkills();
        elseif page == SPECIAL_SKILL_ELEMENT then
            skills = table.keys(ElementMagicM.getAllMagics(ME.user));
        elseif page == SPECIAL_SKILL_DRAGON then
            skills = SlimeSkillM.getAllDragonMagic();
        else
            local temp = {
                [SPECIAL_SKILL_LIGHT] = LIGHTER,
                [SPECIAL_SKILL_DARK] = DARK,
                [SPECIAL_SKILL_WATER] = WATER
            };
            local condType = temp[page];
            local total = SkillM.getDungeonSpecialSkills();
            for _, skillId in pairs(total) do
                if SkillM.query(skillId, "style") == condType and
                    MagicStoneM.isStoneSkill(skillId) then
                    -- 把符合条件的加入列表
                    table.insert(skills, skillId);
                end
            end
        end

        -- 获取技能的详细信息
        skills = skills or {};
        for j = 1, #skills do
            local skillId = skills[j];
            skills[j] = {
                skillId = skillId,
                name = SkillM.query(skillId, "name"),
                icon = SkillM.query(skillId, "icon"),
                require_mp = MagicStoneM.calcSkillCost(skillId),
                costType = SkillM.getSkillCostType(skillId)
            };
        end
        specialSkills[page] = skills;
    end

    return specialSkills[index] or {};
end

-- 重置下信息
local resetData = function()
    type2skills = nil;
    rank2skills = nil;
    specialSkills = nil;
end

----- 页面的数据维护END ----------
---------------------------------

-- 构造函数
function UIMagicScrolls:ctor()
    -- 初始化
    self:setName("UIMagicScrolls");
    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    local node = cc.CSLoader:createNode("layout/spell/magic_scrolls.csb");
    self:addChild(node);
    self.node = node;
    local CT = node:getChildByName("CT");
    local panel = CT:getChildByName("pageview");

    self.data = nil;

    -- 注册点击事件
    self:registerTouchEvent(node);

    self.CT = CT;
    local BT = node:getChildByName("BT");
    self.BT = BT;
    self.panel = panel;

    -- 设置静态的界面元素信息
    self:initStaticView();

    -- 适配
    self:resize();

    -- 记录下标签页的Y坐标
    self.tabY = (self.tabs[1]["tab"]):getPositionY();
end

-- 重绘本界面
function UIMagicScrolls:show(dragon)
    self:setVisible(true);

    -- 注册事件处理回调函数
    self:registerEventCallback()

    if dragon == true then
        self.isDragon = true;
        rightTabIndex = 1;
        for index, type in pairs(self.visibleSpecialPages or {}) do
            if type == SPECIAL_SKILL_DRAGON then
                rightTabIndex = index;
                break;
            end
        end
        selectType = MENU_TYPE_SPECIAL;
    else
        self.isDragon = false;
    end

    -- 先收集下特殊页面的标签页信息
    self:collectSpecialTab();

    -- 底部玩家的属性
    self:initAttri();

    -- 其他信息
    if not self:special2normal() then
        self:initView();
    end

    -- 播放标签落下效果
    self:initTabPosition();
    self:playTabEffect();

    -- 隐藏主页面菜单
    if UIDungeonMgr:getCurLevel() then
    	UIDungeonMgr:getCurLevel():hideMenu();
    end
end

-- 还原初始位置
function UIMagicScrolls:resetPos()
    -- 重新适配
    self:resize();
end

-- 还原resetIndex
function UIMagicScrolls:resetIndex()
    rightTabIndex = 1;
    selectType = MENU_TYPE_STYLE;
end

-- 切换系别
function UIMagicScrolls:switchStype(index)
    if selectType == index then return end
    selectType = index;
    if selectType == MENU_TYPE_RANK then
        rightTabIndex = getFirstRank();
    else
        rightTabIndex = 1;
    end
    self:initView();
end

-- 切换魔法标签
function UIMagicScrolls:switchMagic(index)
    if rightTabIndex == index then return end
    rightTabIndex = index;
    self:initView();
end

-- 注册事件处理回调函数
function UIMagicScrolls:registerEventCallback()
    EventMgr.removeAll("UIMagicScrolls");

    -- 关注使用卷轴的事件
    EventMgr.register("UIMagicScrolls", event.USE_SPELL, function(params)
        if self:isVisible() then
            resetData();
            self:initAttri();
            self:initView();
        end
    end);

    -- 关注拆分卷轴的事件
    EventMgr.register("UIMagicScrolls", event.SPLIT_SPELL, function(params)
        if not self:isVisible() then return end
        resetData();
        self:initAttri();
        self:initView();
        local showResolveConfirmAgain = function()
            if UIMgr:getCurrentScene():isOpen("UISpellOperation") and type(params["classId"]) == "number" then
                UISpellOperation:showResolveConfirm(params["classId"]);
            end
        end

        showBonusNotifyForm(getLocStr("spell_split"), { {2, "mp", params["gainMp"]} }, showResolveConfirmAgain);
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            EventMgr.removeAll("UIMagicScrolls");
        end
    end);
end

-- 初始化
function UIMagicScrolls:initView()
    -- 先清空所有页面
    self.panel:removeAllPages();

    -- 绘制右边栏的tab标签
    self:drawMagicTab();

    -- 绘制3个系别
    self:drawStyleTab();

    -- 绘制标题
    self:drawTitle();

    -- 绘制页面里面的内容
    self:drawPage();
end

-- 关闭本页面
function UIMagicScrolls:hideMe()
    self:setVisible(false);
    UIMgr.getCurrentScene():removeFormByName("UIMagicScrolls");
    resetData();
end

------------------------------------------------------------------
-- 绘画翻页控件
-- @param panel             容器
-- @param itemPath          需要加载item节点的路径
-- @param topHGap           item顶部的间隙
-- @param leftWGap          item左边的间隙
-- @param itemWGap          item横向间距
-- @param itemHGap          item纵向间距
-- @param itemH             item的高度
-- @param itemW             item的宽度
-- @param maxGridColumn     一行最大的格数
-- @param totalNum          item总个数
-- @param itemName          子控件的名字 默认后面 1 2 3 4 ...
function UIMagicScrolls:drawPagePanelView(point, panel, itemPath, topHGap, leftWGap, itemWGap, itemHGap, itemW, itemH, maxGridColumn, pageTotalNum, totalNum, itemName,pageName)
    local pageCount = math.ceil(totalNum / pageTotalNum);

    -- 总行数
    local lineCount = math.ceil(pageTotalNum / maxGridColumn);

    -- 先计算总高度
    local totalHeight = lineCount * (itemH + itemHGap) - itemHGap + (topHGap * 2);

    -- 设置panel尺寸
    panel:setContentSize(panel:getContentSize().width, totalHeight);

    local iconNode = cc.CSLoader:createNode(itemPath);
    local widget = replaceNodeWithWidget(iconNode);

    local index = 1;
    self.items = {};
    for i = 1, pageCount do
        local layout = ccui.Layout:create();
        layout:setName("layout");
        layout:setContentSize(panel:getContentSize());
        for j = 1, lineCount do
            for k = 1, maxGridColumn do

                if index > totalNum then
                    break;
                end

                local child = widget:clone();
                child:setName(itemName .. index);

                local x = (k - 1) * (itemW + itemWGap) + itemW / 2 + leftWGap;
                local y = totalHeight - (j * itemH + ( j - 1) * itemHGap)  + itemH / 2 - topHGap;

                point:registerItemTouchEvent(child);
                index = index + 1;

                child:setPositionX(x);
                child:setPositionY(y);

                layout:addChild(child);
                table.insert(self.items, child);
            end
        end
        panel:addPage(layout);
    end
end

-- 将界面的元素属性设置下
function UIMagicScrolls:initStaticView()
    -- 底部玩家的6个属性
    self.attackLabel = findChildByName(self.BT, "attack_attribute/attack_label");
    TextStyleM.setTextStyle(self.attackLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_WHITE, true, -4);

    self.hpLabel = findChildByName(self.BT, "life_attribute/surplus_lift_label");
    TextStyleM.setTextStyle(self.hpLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_WHITE, true, -4);

    self.maxHpLabel = findChildByName(self.BT, "life_attribute/all_life_label");
    TextStyleM.setTextStyle(self.maxHpLabel, TextStyleM.TEXT_SIZE_TINY, TextStyleM.TEXT_COLOR_WHITE, true, -4);

    self.magicLabel = findChildByName(self.BT, "magic_power_attribute/magic_attribute_label");
    TextStyleM.setTextStyle(self.magicLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_WHITE, true, -4);

    self.mpLabel = findChildByName(self.BT, "magic_attribute/surplus_magic_attribute_label");
    TextStyleM.setTextStyle(self.mpLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_WHITE, true, -4);

    self.maxMpLabel = findChildByName(self.BT, "magic_attribute/all_magic_attribute_label");
    TextStyleM.setTextStyle(self.maxMpLabel, TextStyleM.TEXT_SIZE_TINY, TextStyleM.TEXT_COLOR_WHITE, true, -4);

    -- 标题
    self.title = self.CT:getChildByName("title");
    TextStyleM.setTextStyle(self.title, TextStyleM.TEXT_SIZE_LARGE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, nil, nil, nil, nil, nil, true);

    -- 3个系别按钮
    self.tabs = {};
    for i = 1, 3 do
        table.insert(self.tabs, {
            tab = findChildByName(self.node, "CT/tab"..i),
            btn = findChildByName(self.node, "CT/tab"..i.."/btn"),
            frame = findChildByName(self.node, "CT/tab"..i.."/frame"),
            title = findChildByName(self.node, "CT/tab"..i.."/title")
        })
    end
    (self.tabs[1]["title"]):setString(getLocStr("department"));
    (self.tabs[2]["title"]):setString(getLocStr("rank"));
    (self.tabs[3]["title"]):setString(getLocStr("special"));

    -- 右侧的tab标签
    for i = 1, #spellType do
        local spellTypeLabel = findChildByName(self.CT, "btn_spell" .. i .. "/text");
        TextStyleM.setTextStyle(spellTypeLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_WHITE, true, -4);
    end
end

-- 设置玩家的各属性值
function UIMagicScrolls:initAttri()
    -- 设置攻击力
    self.attackLabel:setString(ME.user:getAttack());

    -- 设置当前生命值
    self.hpLabel:setString(ME.user:getHp());

    -- 设置最大生命值
    self.maxHpLabel:setString("/ " .. ME.user:getMaxHp());

    -- 设置魔力值
    self.magicLabel:setString(ME.user:getMagic());

    -- 设置当前魔法值
    self.mpLabel:setString(ME.user:getMp());

    -- 设置最大魔法值
    self.maxMpLabel:setString("/ " .. ME.user:getMaxMp());
end

-- 获取魔法卷轴的阶位名称
local function getRankName(rank)
    return FormulaM.invoke("GET_SPELL_RANK_NAME", rank);
end

-- 绘制界面的标题
function UIMagicScrolls:drawTitle()
    -- 根据pageType和index确定显示内容
    local titleName;
    if selectType == MENU_TYPE_STYLE then
        -- 系别
        titleName = string.format(getLocStr("spell_name_style"), getNameByAttr(spellType[rightTabIndex]));
    elseif selectType == MENU_TYPE_RANK then
        -- 阶位
        titleName = string.format(getLocStr("spell_name_rank"), covertNumToCapital(rightTabIndex));
    else
        -- 特殊
        -- TODO 前两页为贤者之语
        local index = self.visibleSpecialPages[rightTabIndex];
        if SPECIAL_PAGES[index] == SPECIAL_SKILL_LIGHT then
            -- 光系
            titleName = getLocStr("light_stone_skill_title");
        elseif SPECIAL_PAGES[index] == SPECIAL_SKILL_DARK then
            -- 暗系
            titleName = getLocStr("dark_stone_skill_title");
        else
            titleName = getLocStr("special");
        end
    end

    self.title:setString(titleName);
end

-- 重绘特殊技能
function UIMagicScrolls:redrawSpecialSkills()
    if #self.data == 0 then
        -- 如果当前没有技能，需要清理一遍界面
        self:cleanSpecialPage();
    end

    local pageCount = #self.panel:getPages();
    if pageCount <= 0 then
        return;
    end

    for index = 1, #self.data do
        local pageIndex = math.floor((index - 1) / 6);
        local page = self.panel:getPage(pageIndex);
        if page == nil then
            return;
        end

        local child = page:getChildByName("magic" .. index);
        if child == nil then
            return;
        end

        local info = self.data[index];
        local skillId = info["skillId"];

        -- 设置技能图标
        local iconImg  = child:getChildByName("magic_pic");
        local bgImg    = findChildByName(child, "bg");
        local costImg  = findChildByName(child, "cost");
        local ownImg   = findChildByName(child, "own");
        iconImg:loadTexture(getSkillIconPath(info["icon"]));

        -- 获取需要消耗的魔法值
        local requireMp = info["require_mp"];
        local requireMpLabel = findChildByName(child, "use");

        -- 显示拥有的消耗品
        local ownMpLabel = findChildByName(child, "count");

        -- TODO:
        local isSlimeSkill = false;
        local curEnergy = 0;
        local slimeSkillId;
        if SlimeSkillM.isSlimeSkill(skillId) then
            isSlimeSkill = true;
            slimeSkillId = SlimeSkillM.getSlimeActiveSkillId(skillId);

            local energy = SlimeSkillM.calcUserEnergyCost(slimeSkillId);

            local key = table.keys(energy)[1];
            if type(key) == 'number' then
                curEnergy = ItemM.getAmount(ME.user, key);
            else
                curEnergy = DungeonServiceM.queryDungeonAttrib(key);
            end

            local dbase = SlimeSkillM.query(slimeSkillId, "dbase") or {};

            if dbase["cost_all"] then
                -- 消耗全部属性，至少为1
                requireMp = curEnergy;
                requireMp = math.max(requireMp, 1);
            else
                requireMp = table.values(energy)[1];
            end
        end

        -- 龙语魔法
        local isDragonMagic = false;
        local dragonMagicId;
        if SlimeSkillM.isDragonMagic(skillId) then
            isDragonMagic = true;
            dragonMagicId = SlimeSkillM.getDragonMagicSkillId(skillId);

            local energy = SlimeSkillM.calcUserEnergyCost(dragonMagicId);

            local key = table.keys(energy)[1];
            curEnergy = DungeonServiceM.queryDungeonAttrib(key);
            requireMp = table.values(energy)[1];
        end

        if not requireMp then
            local spellId = SpellM.getSpellId(skillId);
            requireMp = SpellM.calcSpellCost(spellId);
        end

        -- 获取消耗类型
        local costType = info["costType"];

        -- 如果魔法值不足，则需要红色显示
        local curMp = ME.user:getMp();
        local frameImg = findChildByName(child, "bg");
        if isSlimeSkill then
            -- 冈布奥专属技
            if costType == "spell" then
                costType = "slime";
            end
            if requireMp > curEnergy then
                TextStyleM.setTextStyle(requireMpLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_LIGHT_RED, true, -4);
            else
                TextStyleM.setTextStyle(requireMpLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -4);
            end
        elseif costType == "item" then
            -- 装备技能
            if requireMp > curMp then
                TextStyleM.setTextStyle(requireMpLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_LIGHT_RED, true, -4);
            else
                TextStyleM.setTextStyle(requireMpLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -4);
            end
        elseif isDragonMagic then
            -- 龙语魔法
            if costType == "spell" then
                costType = "dragon";
            end
            if requireMp > curEnergy then
                TextStyleM.setTextStyle(requireMpLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_LIGHT_RED, true, -4);
            else
                TextStyleM.setTextStyle(requireMpLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -4);
            end
        else
            -- 魔法技能
            if requireMp > curMp then
                TextStyleM.setTextStyle(requireMpLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_LIGHT_RED, true, -4);
            else
                TextStyleM.setTextStyle(requireMpLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -4);
            end
        end

        -- 显示为正数
        requireMp = math.abs(requireMp);
        requireMpLabel:setString(requireMp);

        -- 重绘卷轴的显示（需求、拥有图标等）
        self:redrawScrollNode(child, costType);

        local level;

        -- 石柱技能和冈布奥专属技需要特殊处理下
        if MagicStoneM.isStoneSkill(skillId) then
            local stoneId = MagicStoneM.getStoneIdBySkill(skillId)
            level = MagicStoneM.getStoneLevel(stoneId);
        elseif isSlimeSkill then
            level = SlimeSkillM.getSkillLevel(slimeSkillId);
        else
            level = SkillM.query(skillId, "level");
        end
        TextStyleM.setTextStyle(ownMpLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -4);
        ownMpLabel:setString(getLevelStr(level));

        -- 技能名字
        local rankTextControl = child:getChildByName("name");

        -- 判断下能否使用，不满足条件的红色显示
        local ret = self:canUseSkill(skillId);
        if ret == true then
            iconImg:setOpacity(255);
            bgImg:setOpacity(255);
            costImg:setOpacity(255);
            ownImg:setOpacity(255);
            requireMpLabel:setOpacity(255);
            ownMpLabel:setOpacity(255);
            rankTextControl:setOpacity(255);
        else
            iconImg:setOpacity(77);
            bgImg:setOpacity(128);
            costImg:setOpacity(77);
            ownImg:setOpacity(77);
            requireMpLabel:setOpacity(165);
            ownMpLabel:setOpacity(165);
            rankTextControl:setOpacity(165);
        end

        TextStyleM.setTextStyle(rankTextControl, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_BROWN);
        rankTextControl:setString(info["name"]);

        child.classId = skillId;
    end
end

-- 适配
function UIMagicScrolls:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 获取底部菜单高度Y
function UIMagicScrolls:getBottomMenuHeightY()
    local h = cc.Director:getInstance():getOpenGLView():getFrameSize().height;
    return 86 * h / DESIGN_HEIGHT;
end

-- 获取底部菜单高度
function UIMagicScrolls:getBottomMenuHeight()
    local w = cc.Director:getInstance():getOpenGLView():getFrameSize().width;
    return 86 * w / DESIGN_WIDTH;
end

-- 对魔法卷轴进行排序 排序按阶位升序排列
function sortMagic(item1, item2)
    if item1["rank"] < item2["rank"] then
        return true;
    elseif item1["rank"] == item2["rank"] then
        if item1["classId"] < item2["classId"] then
            return true;
        else
            return false;
        end
    else
        return false;
    end
end

function UIMagicScrolls:showSpellOperation(node)
    -- 新手关卡引导未完成，禁止查看卷轴信息，防止引导中断或卡住
    if not DungeonGuideM.isGuideFinished() then
        return;
    end

    node.isLongPress = true;

    if selectType == MENU_TYPE_SPECIAL then
        local skillId = node.classId;

        -- 计算魔法值消耗（暂时只要考虑石柱技能）
        local requireMp;
        if MagicStoneM.isStoneSkill(skillId) then
            requireMp = MagicStoneM.calcSkillCost(skillId);
        elseif ElementMagicM.ownElementMagic(ME.user, skillId) then
            -- 先转化成卷轴
            local spellId = SpellM.getSpellId(skillId);
            requireMp = SpellM.calcSpellCost(spellId);
        elseif SlimeSkillM.isSlimeSkill(skillId) then
            -- 冈布奥主动技能-转化成对应的id
            local slimeSkillId = SlimeSkillM.getSlimeActiveSkillId(skillId);

            -- 消耗的能量
            local energy = SlimeSkillM.calcUserEnergyCost(slimeSkillId);
            local dbase = SlimeSkillM.query(slimeSkillId, "dbase") or {};

            if dbase["cost_all"] then
                -- 消耗全部属性，至少为1
                local key = table.keys(energy)[1];
                if type(key) == 'number' then
                    requireMp = ItemM.getAmount(ME.user, key);
                else
                    requireMp = DungeonServiceM.queryDungeonAttrib(key);
                end

                requireMp = math.max(requireMp, 1);
            else
                requireMp = table.values(energy)[1];
            end
        elseif SlimeSkillM.isDragonMagic(skillId) then
            -- 冈布奥主动技能-转化成对应的id
            local dragonMagicId = SlimeSkillM.getDragonMagicSkillId(skillId);

            -- 消耗的能量
            local energy = SlimeSkillM.calcUserEnergyCost(dragonMagicId);
            requireMp = table.values(energy)[1];
        end

        -- 打开技能悬浮界面
        showSkillTooltip(skillId, requireMp);
        return;
    end

    -- 打开卷轴操作界面
    UIMgr.getCurrentScene():removeFormByName("UISpellOperation");
    local uiSpellOperation = UISpellOperation.create(node.classId);
    UIMgr.getCurrentScene():addForm(uiSpellOperation);
end

function UIMagicScrolls:canUseSpell(classId)
    local msg;
    local spellInfo = SpellM.query(classId);
    local name = spellInfo["desc"];

    -- 1.无法使用，需要技能支持
    local canuse = FormulaM.invoke("CAN_USE_SPELL", classId);
    if true ~= canuse then
        -- 公式返回提示的，直接给出
        if type(canuse) == "string" then
            return canuse;
        end
        msg = string.format(getLocStr("cannot_use_spell"), name);
        -- 提示需要学习称号，按宠物系别、链接判断
        local pet = ME.user:getActivePet();
        if pet then
            local depList  = CareerM.getDepartmentList(pet);
            if depList[1] == 1 or depList[1] == 4 and table.indexOf(depList, 1) ~= -1 and table.indexOf(depList, 2) == -1 then
                msg = msg .. "\n" .. getLocStr("spell_need_career");
            else
                msg = msg .. "\n" .. getLocStr("spell_need_career2");
            end
        end
        return msg;
    end

    -- 2.魔法值不足，无法使用魔法
    local curMp = ME.user:getMp() or 0;
    if SpellM.calcSpellCost(classId) > curMp then
        msg = string.format(getLocStr("no_enough_mp_use"), name);
        return msg;
    end

    -- 3.被石柱禁魔了
    if MagicStoneM.isForbidMagic() then
        return getLocStr("forbid_magic_tip");
    end

    -- 禁魔状态
    local prop = PropM.combine(ME.user, "forbidden_magic", 1);
    if PropM.apply(prop, 1) > 0 then
        return getLocStr("forbidden_magic_tip");
    end

    -- 通过检查了
    return true;
end

function UIMagicScrolls:useSpell(classId)
    local ret = self:canUseSpell(classId);

    if type(ret) == "string" then
        -- 不满足条件
        alert(ret, nil, 0.5);
        if not UIDungeonMgr:getCurLevel() then
            return;
        end
        UIDungeonMgr:getCurLevel():showMenu();
        return;
    end

    -- 打开选择目标界面
    if UIMgr.getCurrentScene():isOpen("UISelectTarget") then
        UIMgr.getCurrentScene():removeFormByName("UISelectTarget");
    end

    local uiSelectTarget = UISelectTarget.create(classId);
    UIMgr.getCurrentScene():addForm(uiSelectTarget);
end

-- 判断能否使用技能
function UIMagicScrolls:canUseSkill(skillId)
    -- TODO: 当前仅考虑石柱技能和冈布奥专属技能
    if MagicStoneM.isForbidMagic() then
        -- 被石柱禁魔了
        return getLocStr("forbid_magic_tip");
    end

    -- 禁魔状态
    local prop = PropM.combine(ME.user, "forbidden_magic", 1);
    if PropM.apply(prop, 1) > 0 then
        return getLocStr("forbidden_magic_tip");
    end

    -- 如果是冈布奥专属技能
    if SlimeSkillM.isSlimeSkill(skillId) then
        local slimeSkillId = SlimeSkillM.getSlimeActiveSkillId(skillId);
        local energy = SlimeSkillM.calcUserEnergyCost(slimeSkillId);
        local cost = table.values(energy)[1];

        local key = table.keys(energy)[1];
        local curEnergy, maxEnergy;
        if type(key) == 'number' then
            curEnergy = ItemM.getAmount(ME.user, key);
        else
            curEnergy = DungeonServiceM.queryDungeonAttrib(key);
            maxEnergy = DungeonServiceM.getDungeonAttribInfo(key, "limit");
        end

        local dbase = SlimeSkillM.query(slimeSkillId, "dbase") or {};
        if dbase["cost_all"] then
            -- 如果是消耗全部属性的，至少为1
            cost = curEnergy;
            cost = math.max(cost, 1);
        end

        if maxEnergy ~= nil and cost > maxEnergy then
            -- 特殊情况，消耗高于上限了
            return getLocStr("skill_limit_scene");
        end

        -- 能量值不足
        if cost > curEnergy then
            local name;
            if type(key) == "number" then
                name = ItemM.query(key, "name");
            else
                name = DungeonServiceM.getDungeonAttribInfo(key, "name");
                if not name then
                    name = FieldsM.getFieldName(key);
                end
            end
            return string.format(getLocStr("lack_skill_energy"), name);
        end
    end

    -- 如果是龙语魔法
    if SlimeSkillM.isDragonMagic(skillId) then
        local dragonSkill = SlimeSkillM.getDragonMagicSkillId(skillId);
        local energy = SlimeSkillM.calcUserEnergyCost(dragonSkill);
        local cost = table.values(energy)[1];

        local key = table.keys(energy)[1];
        local curEnergy;

        curEnergy = DungeonServiceM.queryDungeonAttrib(key);

        -- 能量值不足
        if cost > curEnergy then
            local name;
            name = DungeonServiceM.getDungeonAttribInfo(key, "name");
            if not name then
                name = FieldsM.getFieldName(key);
            end
            return string.format(getLocStr("lack_skill_energy"), name);
        end
    end

    -- 石柱技能
    if  MagicStoneM.isStoneSkill(skillId) then
        if MagicStoneM.checkApply(skillId) == "full_attrib" then
            return getLocStr("full_attrib");
        elseif MagicStoneM.checkApply(skillId) ~= true then
            -- 魔法值不足
            return getLocStr("no_enough_mp");
        end
    end

    return true;
end

-- 尝试使用技能
function UIMagicScrolls:tryUseSkill(skillId)
    -- 判断能否使用技能
    local ret = self:canUseSkill(skillId);
    if ret ~= true then
        -- 不满足条件
        if type(ret) == 'string' then
            -- alert(ret);
            local list = splitString(ret, "\n");
            splitAlert(list);
        else
            cclog("技能(%d)不满足施放条件。", skillId);
        end

        if not UIDungeonMgr:getCurLevel() then
            return;
        end
        UIDungeonMgr:getCurLevel():showMenu();
        return;
    end

    -- 打开技能选择目标界面
    UIMgr.getCurrentScene():removeFormByName("UIStoneSelectTarget");
    local uiForm = UIStoneSelectTarget.create(skillId);
    UIMgr.getCurrentScene():addForm(uiForm);
end

-- 注册魔法卷轴点击事件
function UIMagicScrolls:registerItemTouchEvent(node)
    local image = node:getChildByName("bg");
    local function onClick(sender, eventType)
        -- 点击处理
        local function doClickScroll()
            if selectType == MENU_TYPE_SPECIAL then
                -- 走技能施法流程
                self:tryUseSkill(node.classId);
            else
                -- 走使用卷轴流程
                self:useSpell(node.classId);
            end

            -- 关闭当前界面
            self:hideMe();
        end


        -- 新手引导还没结束, 无法长按，防止引导中断
        if DungeonM.getDungeonId() == 11 and DungeonM.currentLayer() == 1
            and not DungeonGuideM.isGuideFinished() then
            if eventType == ccui.TouchEventType.began then
            elseif eventType == ccui.TouchEventType.ended then
                doClickScroll();
            end
            return;
        end

        local function longPressCallback()
            self:showSpellOperation(node);
        end

        -- 处理长按
        if handleLongPress(sender, eventType, longPressCallback) then
            return;
        end

        if eventType == ccui.TouchEventType.ended then
            doClickScroll();
        end
    end
    AddTouchEventListener(image, onClick);
end

-- 注册点击事件
function UIMagicScrolls:registerTouchEvent(node)
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            self:hideMe();
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    for i = 1, MAGIC_KINDS_COUNT do
        local btn = findChildByName(node, string.format("CT/btn_spell%d", i));
        btn.index = i;
        local function onClick(sender, eventType)
            if eventType == ccui.TouchEventType.ended then
                AudioM.playFx("ui_open2");
                self:switchMagic(sender.index);
            end
        end
        btn:addTouchEventListener(onClick);
    end

    -- 系别按钮
    local btnDepartment = findChildByName(node, "CT/tab1/btn");
    local function onDepartmentClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("ui_open2");
            self:switchStype(MENU_TYPE_STYLE);
        end
    end
    btnDepartment:addTouchEventListener(onDepartmentClick);

    -- 阶位按钮
    local btnRank = findChildByName(node, "CT/tab2/btn");
    local function onRankClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("ui_open2");
            self:switchStype(MENU_TYPE_RANK);
        end
    end
    btnRank:addTouchEventListener(onRankClick);

    -- 特殊按钮
    local btnSpecial = findChildByName(node, "CT/tab3/btn");
    local function onSpecialClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("ui_open2");
            self:switchStype(MENU_TYPE_SPECIAL);
        end
    end
    btnSpecial:addTouchEventListener(onSpecialClick);
end

-- 清理特殊页
function UIMagicScrolls:cleanSpecialPage()
    -- 隐藏所有的特殊页标签
    for i = 1, #spellType do
        local btn = findChildByName(self.CT, "btn_spell" .. i);
        local btnFrame = findChildByName(self.CT, "frame_spell" .. i);
        btn:setVisible(false);
        btnFrame:setVisible(false);
    end

    -- 隐藏标题
    local titleLabel = self.CT:getChildByName("title");
    titleLabel:setString("");
end

-- 绘制3个系别
function UIMagicScrolls:drawStyleTab()
    for i = 1, 3 do
        if i == selectType then
            (self.tabs[i]["btn"]):setHighlighted(true);
            (self.tabs[i]["btn"]):setColor(TextStyleM.TEXT_COLOR_NORMAL);
            (self.tabs[i]["frame"]):setVisible(true);
            TextStyleM.setTextStyle(self.tabs[i]["title"], TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
        else
            (self.tabs[i]["btn"]):setHighlighted(false);
            (self.tabs[i]["btn"]):setColor(TextStyleM.TEXT_COLOR_BLEND);
            (self.tabs[i]["frame"]):setVisible(false);
            TextStyleM.setTextStyle(self.tabs[i]["title"], TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_GRAY, true);
        end
    end

    -- 如果没有特殊技能，则隐藏特殊标签
    local skills = SkillM.getDungeonSpecialSkills();
    (self.tabs[3]["tab"]):setVisible(#skills > 0);
end

-- 特殊分页下，那些标签页需要被显示
function UIMagicScrolls:collectSpecialTab()
    self.visibleSpecialPages = {};
    for i = 1, #spellType do
        local skills = getSpecialSkills(SPECIAL_PAGES[i]);
        if skills ~= nil and #skills > 0 then
            -- 仅显示技能个数大于0的页
            table.insert(self.visibleSpecialPages, i);
        end
    end
    if rightTabIndex > #self.visibleSpecialPages and selectType == MENU_TYPE_SPECIAL then
        rightTabIndex = 1;
    end
end

-- 绘制右边栏的tab标签
function UIMagicScrolls:drawMagicTab()
    for i = 1, #spellType do
        local btn = findChildByName(self.CT, "btn_spell" .. i);
        local label = findChildByName(btn, "text");
        local btnFrame = findChildByName(self.CT, "frame_spell" .. i);
        local btnIcon = findChildByName(btn, "btn_icon" .. i);
        btn:setVisible(true);
        btnFrame:setVisible(false);
        btnIcon:removeAllChildren();
        TextStyleM.setTextStyle(label, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_WHITE, true, -4);

        -- 选中高亮
        if rightTabIndex == i then
            btn:setHighlighted(true);
            btn:setColor(TextStyleM.TEXT_COLOR_NORMAL);
        else
            btn:setHighlighted(false);
            btn:setColor(TextStyleM.TEXT_COLOR_BLEND);
        end

        if selectType == MENU_TYPE_STYLE then
            local skills = getSkillsByType(spellType[i]);
            if nil == skills or skills["count"] == 0 then
                label:setVisible(false);
            else
                -- 增加图标的子控件
                local styleIcon = ccui.ImageView:create("images/ui/magic/style" .. i .. ".png");
                btnIcon:addChild(styleIcon);
                label:setString(skills["count"]);
                label:setVisible(true);
            end
            if rightTabIndex == i then btnFrame:setVisible(true) end
        elseif selectType == MENU_TYPE_RANK then
            local skills = getSkillsByRank(i);
            -- 设置阶位的子控件
            local rankLayer = createStarLayer(i, "images/ui/symbol/star_little.png", "center", -0.3);
            local posX = rankLayer:getPositionX();
            local posY = rankLayer:getPositionY();
            local btnIconHeight = btnIcon:getContentSize().height;
            local rankHeight = rankLayer:getContentSize().height;
            if i > 5 then
                btn:setVisible(false);
            else
                rankLayer:setPosition(posX, posY - 28);
                rankLayer:setScale(0.6);
                btnIcon:addChild(rankLayer);
                btn:setVisible(true);
            end
            if nil == skills or skills["count"] == 0 then
                btnFrame:setVisible(false);
                label:setVisible(false);
            else
                label:setString(skills["count"]);
                btn:setVisible(true);
                label:setVisible(true);
            end
            if rightTabIndex == i then btnFrame:setVisible(true) end
        end
    end

    -- 特殊页的标签在下面绘制
    if selectType ~= MENU_TYPE_SPECIAL then return end
    local count = #self.visibleSpecialPages;
    for i, index in pairs(self.visibleSpecialPages) do
        local btn = findChildByName(self.CT, "btn_spell" .. i);
        local btnIcon = findChildByName(btn, "btn_icon" .. i);
        local label = findChildByName(btn, "text");
        local btnFrame = findChildByName(self.CT, "frame_spell" .. i);
        TextStyleM.setTextStyle(label, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_WHITE, true);

        -- 增加标签的子控件
        local iconPath = "images/ui/magic/special_style" .. SPECIAL_PAGES[index] .. ".png"
        local styleIcon = ccui.ImageView:create(iconPath);
        btnIcon:addChild(styleIcon);

        -- 显示技能个数
        local skills = getSpecialSkills(SPECIAL_PAGES[index]);
        label:setString(#skills);
        btn:setVisible(true);
        label:setVisible(true);

        if rightTabIndex == i then btnFrame:setVisible(true) end
    end
    for i = count + 1, #spellType do
        local btn = findChildByName(self.CT, "btn_spell" .. i);
        btn:setVisible(false);
    end
end

-- 绘制页面里面的具体内容
function UIMagicScrolls:drawPage()
    if selectType == MENU_TYPE_STYLE then
        self.data = getSkillsByType(spellType[rightTabIndex])["list"];
    elseif selectType == MENU_TYPE_RANK then
        local data = getSkillsByRank(rightTabIndex);
        if data == nil then
            self.data = {};
        else
            self.data = data["list"];
        end
    else
        local index = self.visibleSpecialPages[rightTabIndex];
        self.data = getSpecialSkills(SPECIAL_PAGES[index]);
    end

    self:drawPagePanelView(self, self.panel,
        "layout/spell/MagicScrollsItem.csb",
        0,  -- topHGap
        10, -- leftWGap,
        0,  -- wGap,
        30, -- hGap,
        221,-- iconWidth,
        130,-- iconHeight,
        MAX_GRID_COLUMN,
        6,
        #(self.data),
        "magic", "magic_page");

    if selectType == MENU_TYPE_SPECIAL then
        -- 当前选中的是特殊菜单
        self:redrawSpecialSkills();
        return;
    end

    -- 绘制每页中技能格子的信息
    local allPage = self.panel:getPages();
    local page = self.panel:getPage(0);
    if not page then
        return;
    end
    for index = 1, #self.data do
        local child = page:getChildByName("magic" .. index);
        if child == nil then
            return;
        end

        local info = self.data[index];
        local classId = info["classId"];
        local skillId = info["cast_skill_id"];

        -- 设置魔法头像
        local magicPic = child:getChildByName("magic_pic");
        local bgImg    = findChildByName(child, "bg");
        local costImg  = findChildByName(child, "cost");
        local ownImg   = findChildByName(child, "own");
        magicPic:loadTexture(getSkillIconPath(info["icon"]));

        -- 获取需要消耗的魔法值
        local require_mp = info["require_mp"];
        local magicUseControl = child:getChildByName("use");

        -- 如果英雄魔法值不足以施放该魔法，则需要红色显示
        local curMp = ME.user:getMp();
        if require_mp > curMp then
            TextStyleM.setTextStyle(magicUseControl, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_LIGHT_RED, true, -4);
        else
            TextStyleM.setTextStyle(magicUseControl, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -4);
        end
        magicUseControl:setString(require_mp);

        -- 获取魔法卷轴拥有的数量
        local countArt = child:getChildByName("count");
        TextStyleM.setTextStyle(countArt, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -4);
        countArt:setString(info["count"]);
        countArt:setVisible(true);

        -- 魔法阶级
        local rankText = getRankName(info["rank"]);

        -- 魔法名字
        local rankTextControl = child:getChildByName("name");

        -- 判断下能否使用，不满足条件的红色显示
        if self:canUseSpell(classId) == true then
            magicPic:setOpacity(255);
            bgImg:setOpacity(255);
            costImg:setOpacity(255);
            ownImg:setOpacity(255);
            magicUseControl:setOpacity(255);
            countArt:setOpacity(255);
            rankTextControl:setOpacity(255);
        else
            magicPic:setOpacity(77);
            bgImg:setOpacity(128);
            costImg:setOpacity(77);
            ownImg:setOpacity(77);
            magicUseControl:setOpacity(165);
            countArt:setOpacity(165);
            rankTextControl:setOpacity(165);
        end

        TextStyleM.setTextStyle(rankTextControl, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_BROWN);
        rankTextControl:setString(string.format("%s.%s", getRomanNumeral(info["rank"]), info["name"]));

        child.classId = classId;
    end
end

-- 初始化播放效果前标签的位置
function UIMagicScrolls:initTabPosition()
    local vOffset = 75;
    for i = 1, 3 do
        local tab = self.tabs[i]["tab"];
        tab:stopAllActions();
        tab:setPositionY(self.tabY + vOffset);
    end
end

-- 标签落下的效果
function UIMagicScrolls:playTabEffect()
    local vOffset = 75;

    local function play()
        -- 掉落并小幅回弹
        local function dropDown(node, index)
            local pos = cc.p(node:getPosition());
            local delay = cc.DelayTime:create(0.15 * (index - 1));
            local moveDown = cc.MoveTo:create(0.2, cc.p(pos.x, pos.y - vOffset - 5));
            local moveBack = cc.MoveTo:create(0.1, cc.p(pos.x, pos.y - vOffset));
            local action = cc.Sequence:create(delay, moveDown, moveBack);
            node:runAction(action);
        end

        for i = 1, 3 do
            local tab = self.tabs[i]["tab"];
            dropDown(tab, i);
        end
    end

    -- tab的动画效果
    performWithDelay(self, play, 0.2);
end

-- 初始选中第一页
function UIMagicScrolls:special2normal()
    if selectType == MENU_TYPE_SPECIAL then
        local skills = SkillM.getDungeonSpecialSkills();
        if #skills == 0 then
            self:switchStype(MENU_TYPE_STYLE);
            return true;
        end
    end
    return false;
end

function UIMagicScrolls:redrawScrollNode(scrollNode, costType)
    local costImg = findChildByName(scrollNode, "cost");
    local ownImg  = findChildByName(scrollNode, "own");

    costImg:loadTexture(getSpellCostIcon(costType));
    ownImg:loadTexture(getSpellOwnIcon(costType));
end

function UIMagicScrolls:getSpecialIndex(childType)
    -- 获取特殊页标签索引
    local pos = 0;
    for k, v in pairs(SPECIAL_PAGES) do
        -- 记录需要显示的特殊页标签索引
        if type(v) == 'number' then
            -- 获取该页特殊技能的个数
            local skills = getSpecialSkills(v);

            local count = #skills;
            if count > 0 then
                pos = pos + 1;
                if v == childType then
                    return pos;
                end
            end
        end
    end

    return 1;
end